package com.lzy.canal.util;

import com.google.gson.TypeAdapter;
import com.google.gson.internal.LinkedTreeMap;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Map;

/**
 * 自定义反序列化map对象
 *
 */
@Slf4j
public class MapTypeAdapter extends TypeAdapter<Object> {
    @Override
    public void write(JsonWriter out, Object value) {

    }

    @Override
    public Object read(JsonReader in) throws IOException {
        JsonToken jsonToken = in.peek();
        if (JsonToken.BEGIN_ARRAY.equals(jsonToken)) {
            ArrayList<Object> list = new ArrayList<>();
            in.beginArray();
            while (in.hasNext()) {
                list.add(read(in));
            }
            in.endArray();
            return list;
        }
        if (JsonToken.BEGIN_OBJECT.equals(jsonToken)) {
            Map<String, Object> map = new LinkedTreeMap<>();
            in.beginObject();
            while (in.hasNext()) {
                map.put(in.nextName(), read(in));
            }
            in.endObject();
            return map;
        }
        if (JsonToken.STRING.equals(jsonToken)) {
            return in.nextString();
        }
        if (JsonToken.NUMBER.equals(jsonToken)) {
            try {
                BigDecimal decimalVal = new BigDecimal(in.nextString());
                if (decimalVal.scale() <= 0 || decimalVal.stripTrailingZeros().scale() <= 0) {
                    return decimalVal.longValueExact();
                }
            } catch (Exception e) {
                log.debug("反序列化失败,", e);
            }
            return null;
        }
        if (JsonToken.BOOLEAN.equals(jsonToken)) {
            return in.nextBoolean();
        }
        if (JsonToken.NULL.equals(jsonToken)) {
            in.nextNull();
            return null;
        }
        throw new IllegalStateException();
    }
}
